package com.sit.estatemanagementserver.controller;

import com.alibaba.fastjson2.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.security.Signature;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Base64;

@Controller
public class VisitorVerifyController {

    @Autowired
    private java.security.KeyPair keyPair;

    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    @GetMapping("/visitor/verify")
    public String verifyVisitor(@RequestParam("data") String data, @RequestParam("sig") String sig, Model model) {
        try {
            // --- 步骤 1 & 2: 解码数据和签名 (保持不变) ---
            String standardSig = sig.replace('-', '+').replace('_', '/');
            byte[] signatureBytes = Base64.getDecoder().decode(standardSig);
            byte[] jsonDataBytes = Base64.getUrlDecoder().decode(data);
            String jsonData = new String(jsonDataBytes, StandardCharsets.UTF_8);

            // --- 步骤 3: 验证签名 (保持不变) ---
            PublicKey publicKey = keyPair.getPublic();
            Signature publicSignature = Signature.getInstance("SHA256withRSA");
            publicSignature.initVerify(publicKey);
            publicSignature.update(jsonData.getBytes(StandardCharsets.UTF_8));

            if (!publicSignature.verify(signatureBytes)) {
                setModelAttributes(model, "验证失败", "凭证无效或已被篡改。", "red");
                return "verify_result";
            }

            // --- 步骤 4: 签名通过，解析JSON并检查时间窗口 ---
            JSONObject json = JSONObject.parseObject(jsonData);
            long exp = json.getLong("exp"); // 过期时间戳
            long nbf = json.getLong("nbf"); // 生效时间戳 (Not Before)
            long now = Instant.now().getEpochSecond(); // 当前时间戳

            // 格式化时间以供显示
            LocalDateTime expiryDateTime = toLocalDateTime(exp);
            LocalDateTime startDateTime = toLocalDateTime(nbf);
            String formattedExpiry = expiryDateTime.format(FORMATTER);
            String formattedStart = startDateTime.format(FORMATTER);

            // 核心逻辑修改：增加对nbf(生效时间)的判断
            if (now < nbf) {
                setModelAttributes(model, "凭证尚未生效", "该访客凭证将于 " + formattedStart + " 生效。", "orange");
            } else if (now > exp) {
                setModelAttributes(model, "凭证已过期", "该访客凭证已于 " + formattedExpiry + " 过期。", "orange");
            } else {
                String info = String.format("访客: %s<br>到访房间: %s<br>有效时间: %s 至 %s",
                        json.getString("visitorName"),
                        json.getString("visitingRoomNumber"),
                        formattedStart,
                        formattedExpiry);
                setModelAttributes(model, "验证通过", info, "green");
            }

        } catch (Exception e) {
            e.printStackTrace();
            setModelAttributes(model, "验证异常", "凭证格式错误，无法解析。", "red");
        }

        return "verify_result";
    }

    // 辅助方法，避免重复代码
    private void setModelAttributes(Model model, String status, String message, String color) {
        model.addAttribute("status", status);
        model.addAttribute("message", message);
        model.addAttribute("color", color);
    }

    // 辅助方法，将时间戳转换为LocalDateTime
    private LocalDateTime toLocalDateTime(long epochSecond) {
        return LocalDateTime.ofInstant(Instant.ofEpochSecond(epochSecond), ZoneId.systemDefault());
    }
}